/** * Filename: RedpinStandaloneServer.java (in org.repin.server.standalone) * This file is part of the Redpin project. * * Redpin is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * any later version. * * Redpin is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Redpin. If not, see <http://www.gnu.org/licenses/>. * * (c) Copyright ETH Zurich, Pascal Brogle, Philipp Bolliger, 2010, ALL RIGHTS RESERVED. * * www.redpin.org */ package org.redpin.server.standalone; import java.io.IOException; import java.net.ServerSocket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; import org.redpin.server.standalone.net.ConnectionHandler; import org.redpin.server.standalone.svm.TrainSVMTimerTask; import org.redpin.server.standalone.util.Configuration; import org.redpin.server.standalone.util.Log; /** * Basic class of the redpin standalone server * * * @author Pascal Brogle (broglep@student.ethz.ch) * */ public class RedpinStandaloneServer implements Runnable { /** * Does start the standalone server * * @param args configuration */ public static void main(String[] args) { initConfig(args); startServer(); } private final ServerSocket serverSocket; private final ExecutorService threadPool; private static Logger log; private boolean running; /** * creates a new server instance * * @param port Port number * @throws IOException */ public RedpinStandaloneServer(int port) throws IOException { serverSocket = new ServerSocket(port); threadPool = Executors.newCachedThreadPool(); log = Log.getLogger(); } /** * sets the configuration according to the arguments * @param args configuration */ public static void initConfig(String[] args) { if(args.length > 0) { Configuration.ServerPort = new Integer(args[0]); } } /** * starts the server by creating an instance an run it */ public static void startServer() { try { RedpinStandaloneServer server = new RedpinStandaloneServer(Configuration.ServerPort); new Thread(server).start(); Runtime.getRuntime().addShutdownHook(new Thread(server.new ShutdownHandler(server))); TrainSVMTimerTask.start(); } catch (IOException e) { Log.getLogger().log(Level.SEVERE, "Failed to start server", e); e.printStackTrace(); } } /** * waits for incoming connection, accepts and passes them to the connection handler */ public void run() { log.info("Started server at " + serverSocket.getInetAddress().getHostName() + ":"+ serverSocket.getLocalPort() ); running = true; try { while(running) { threadPool.execute(new ConnectionHandler(serverSocket.accept())); } } catch (IOException ex) { if(running) { log.log(Level.SEVERE, "caught io execpton: "+ex.getMessage(), ex); } else { log.fine(ex.getMessage()); } } threadPool.shutdown(); log.fine("Shutting down thread pool..."); while(!threadPool.isTerminated()) { try { Thread.sleep(1000); } catch (InterruptedException e) {} } log.fine("Thread pool shut down"); synchronized (this) { notifyAll(); } System.out.println("Stopped server at " + serverSocket.getInetAddress().getHostName() + ":"+ serverSocket.getLocalPort() ); } /** * stops the server. */ public void stopServer() { log.info("Stopping server..."); running = false; try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } public class ShutdownHandler implements Runnable { RedpinStandaloneServer server = null; public ShutdownHandler(RedpinStandaloneServer server) { this.server = server; } //TODO: check synchronization issue (not all messages get logged). system.out.println gets always printed @Override public void run() { log.fine("Control-C caught. Shutting down gracefully..."); //System.out.println("Shutdown Handler: Shutting down gracefully..."); server.stopServer(); try { synchronized (server) { log.info("Waiting for server shutdown..."); //System.out.println("Shutdown Handler: Wait for server shutdown..."); server.wait(); log.info("Server shut down, now quitting..."); //System.out.println("Shutdown Handler: Server shut down, now quitting"); } } catch (InterruptedException e) { e.printStackTrace(); } } } }